package com.explorati.design_pattern.creational.singleton;

/**
 * 静态内部类单例模式 第二种方式解决重排序问题
 * 
 * @author explorati
 *
 */
public class StaticInnerClassSingleton {

	/**
	 * 关键点：看InnerClass对象的初始化锁是哪个线程拿到(这个线程就会去初始化它)，其余线程将停在这个初始化对象的锁上
	 * 
	 * @author explorati
	 *
	 */
	private static class InnerClass {
		private static StaticInnerClassSingleton staticInnerClassSingleton = new StaticInnerClassSingleton();
	}

	public static StaticInnerClassSingleton getInstance() {
		return InnerClass.staticInnerClassSingleton;
	}

	// 私有构造器是必须要有的，否则外部就能new出来了
	private StaticInnerClassSingleton() {
		// 防止反射攻击(对于类加载时实例就创建好的方法)
		if (InnerClass.staticInnerClassSingleton != null) {
			throw new IllegalArgumentException("单例模式禁止反射调用");
		}
	}
	/**
	 * 单例-静态内部类 原理：不让线程1看到重排序 线程0执行时由于Class对象的初始化锁，执行new
	 * Instance()的时候，线程1在获取class对象锁等待，由于静态内部类的加载时封闭的，所以线程1看不到
	 * 
	 * 非构造线程不允许看到重排序 1 . 分配对象的内存空间 3. 设置instance指向内存空间 2. 初始化对象
	 */

	/**
	 * 假设线程0来构造单例对象，初始化一个类包括执行这个类的静态初始化，还有初始化在这个类中声明的静态变量
	 * 
	 */
}
